From bf8898e67641402fa1eb8386c5f3cb7272107ca3 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Thu, 1 Oct 2009 12:25:36 +0100 Subject: [PATCH] Disable HPET broadcast mode on kexec. Without this the new kernel cannot receive timer interrupts from the legacy sources. Hangs are observed in the second kernel's "check_timer()" routing or at "Checking 'hlt' instruction." Signed-off-by: Ian Campbell --- xen/arch/x86/crash.c | 4 ++++ xen/arch/x86/hpet.c | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/crash.c b/xen/arch/x86/crash.c index 009ae9ab7e..1c90b6eca2 100644 --- a/xen/arch/x86/crash.c +++ b/xen/arch/x86/crash.c @@ -25,6 +25,7 @@ #include #include #include +#include static atomic_t waiting_for_crash_ipi; static unsigned int crashing_cpu; @@ -83,6 +84,9 @@ void machine_crash_shutdown(void) nmi_shootdown_cpus(); + if ( hpet_broadcast_is_available() ) + hpet_disable_legacy_broadcast(); + disable_IO_APIC(); hvm_cpu_down(); diff --git a/xen/arch/x86/hpet.c b/xen/arch/x86/hpet.c index 2136169f40..3a560f11fc 100644 --- a/xen/arch/x86/hpet.c +++ b/xen/arch/x86/hpet.c @@ -604,8 +604,9 @@ void hpet_broadcast_init(void) void hpet_disable_legacy_broadcast(void) { u32 cfg; + unsigned long flags; - spin_lock_irq(&legacy_hpet_event.lock); + spin_lock_irqsave(&legacy_hpet_event.lock, flags); legacy_hpet_event.flags |= HPET_EVT_DISABLE; @@ -619,7 +620,7 @@ void hpet_disable_legacy_broadcast(void) cfg &= ~HPET_CFG_LEGACY; hpet_write32(cfg, HPET_CFG); - spin_unlock_irq(&legacy_hpet_event.lock); + spin_unlock_irqrestore(&legacy_hpet_event.lock, flags); smp_send_event_check_mask(&cpu_online_map); } -- 2.30.2